package com.ehais.util;

import android.util.Log;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class SocketManager {
    private static final String TAG="WifiUtil";
    private static ServerThread serverThread = null;
    private static int sum = 0;
    private static Map<String, Socket> clientMap = new HashMap<>();
    private static List<String> clientList = new ArrayList<>();

    private static class ServerThread implements Runnable {

        private ServerSocket server;
        private int port = 5000;
        private boolean isExit = false;// 一个boolean类型的判断 默认是退出状态false

        private OnRequestBack requestBack;

        private String type ;//检测类型  Plumbic 铅酸  Phosphoric 磷酸铁锂

        // 构造方法初始化
        public ServerThread(OnRequestBack _requestBack,String _type) {
            try {
                server = new ServerSocket(port);

                requestBack = _requestBack;
                type = _type;

                Log.i(TAG,"启动server，端口号：" + port +"  , type:"+type);

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        /**
         * 1.获得远程服务器的IP 地址.
         * InetAddress inetAddress = socket.getInetAddress();
         * 2.获得远程服务器的端口.
         * int port = socket.getPort();
         * 3. 获得客户本地的IP 地址.
         * InetAddress localAddress = socket.getLocalAddress();
         * 4.获得客户本地的端口.
         * int localPort = socket.getLocalPort();
         * 5.获取本地的地址和端口号
         * SocketAddress localSocketAddress = socket.getLocalSocketAddress();
         * 6.获得远程的地址和端口号
         * SocketAddress remoteSocketAddress = socket.getRemoteSocketAddress();
         */
        @Override
        public void run() {
            try {
                while (!isExit) {
                    // 等待连接
                    Log.i(TAG,"等待手机的连接中... ...");
                    final Socket socket = server.accept();
                    Log.i(TAG,"获取的手机IP地址及端口号：" + socket.getRemoteSocketAddress().toString());
                    requestBack.onSConnect();//建立socket连接成功
                    /**
                     * 因为考虑到多手机连接的情况 所以加入线程锁 只允许单线程工作
                     */
//                    new Thread(new Runnable() {

                        String text;

//                        @Override
//                        public void run() {
                            try {

                                // 在这里考虑到线程总数的计算 也代表着连接手机的数量
                                ++sum;
                                // 存入到集合和Map中为群发和单独发送做准备
                                String string = socket.getRemoteSocketAddress().toString();
                                clientList.add(string);
                                clientMap.put(string, socket);


//                                synchronized (this) {
                                    // 定义输入输出流
                                    InputStream is = socket.getInputStream();


//                                    private String type ;//检测类型  Plumbic 铅酸  Phosphoric 磷酸铁锂
                                    Log.i(TAG,"捕捉到的:"+type);
                                    if(type.equals("Plumbic")){//Plumbic

                                        byte[] buffer = new byte[2048];
                                        int len;
                                        while ((len = is.read(buffer)) != -1) {
                                            byte[] buffer2 = new byte[len];
                                            System.arraycopy(buffer, 0, buffer2, 0, len);
                                            text = AsciiToHex.toHexAscii(buffer2);
                                            Log.i(TAG,"铅酸收到的数据为  ：" + text);
                                            requestBack.onSuccessPlumbic(text);
                                        }

                                    } else if(type.equals("Phosphoric")){//Phosphoric 磷酸铁锂

                                        BufferedReader br = new BufferedReader(new InputStreamReader(is));
                                        String rec;
                                        while ((rec = br.readLine()) != null) {
                                            Log.i(TAG,"磷酸铁锂收到的数据为  ：" + rec+"  ； 长度："+rec.length());
                                            if(rec.indexOf("~") == 0 && rec.length() > 20){
                                                requestBack.onSuccessPhosphoric(rec);
                                            }
                                        }

                                    }

                            } catch (Exception e) {
                                e.printStackTrace();
                                clientList.clear();
                                clientMap.clear();
                            }

                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // 关闭server
        public void stop() {
            isExit = true;
            if (server != null) {
                try {
                    server.close();
                    Log.i(TAG,"已关闭server");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }





    // 启动server
    public static ServerThread startServer(OnRequestBack _requestBack, String type) {
        Log.i(TAG,"开启server");
        if (serverThread != null) {
            Log.i(TAG,"server不为null正在重启server");
            // 以下为关闭server和socket
            shutDown();
        }
        // 初始化
        serverThread = new ServerThread(_requestBack,type);
        new Thread(serverThread).start();
        Log.i(TAG,"开启server成功");
        return serverThread;
    }



    // 群发的方法
    public static boolean sendMsgAll(String command,String type){
        try {
            command = command.replaceAll(" " ,"").replaceAll("\r" ,"").replaceAll("\n" ,"");

//            Log.i(TAG,"type:"+type +" clientMap "+clientMap.size());


            for (Socket socket : clientMap.values()) {
                OutputStream outputStream = socket.getOutputStream();

                if(type.equals("Plumbic")){//Plumbic
                    outputStream.write(AsciiToHex.hexStringToByte(command));//正式有用的 "00 00 00 00 00 06 01 04 03 E8 00 0A"
                } else if(type.equals("Phosphoric")) {//Phosphoric 磷酸铁锂  26014642E00201FD2F
                    outputStream.write((command+"\r").getBytes());
//                    outputStream.write((command).getBytes());
//                    outputStream.write(AsciiToHex.hexStringToByte(command+"\r"));

//                    PrintWriter printWriter = new PrintWriter(outputStream);
//                    printWriter.write(command+"\r");
//                    printWriter.print(AsciiToHex.hexStringToByte(command));
//                    printWriter.print(toHexAscii(command.getBytes())+"\\CR");
//                    printWriter.print((command+"\r").getBytes());
//                    printWriter.print(toHexAscii((command+"\r").getBytes()));
//                    printWriter.print("\r");
//                    printWriter.print(command+"\r");
//                    printWriter.print("\r");
//                    printWriter.print(b);
//                    printWriter.flush(); // 冲刷，保证数据写入网卡

                }

                Log.i(TAG,"发送指令:"+command+" 到 "+socket.getRemoteSocketAddress().toString());


            }
            return true;
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }


    public static void shutDown() {
        for (Socket socket : clientMap.values()) {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (serverThread != null) serverThread.stop();
        clientMap.clear();
        clientList.clear();
    }







}
